<template>
  <div class="min-h-screen bg-gradient-to-br from-blue-50 to-purple-50 py-8">
    <div class="max-w-4xl mx-auto px-4 sm:px-6 lg:px-8">
      <!-- Header -->
      <div class="text-center mb-8">
        <h1 class="text-3xl font-bold text-gray-900 mb-4">
          <span class="text-gradient">SHA 哈希生成器</span>
        </h1>
        <p class="text-lg text-gray-600">支持 SHA-1 / SHA-256 / SHA-384 / SHA-512，对文本或文件进行哈希计算，支持复制与下载。</p>
      </div>

      <div class="bg-white rounded-xl shadow-lg p-6">
        <!-- Input Area -->
        <div class="mb-6">
          <label class="block text-sm font-medium text-gray-700 mb-2">输入文本</label>
          <textarea
            v-model="inputText"
            placeholder="请输入要计算哈希的文本..."
            class="textarea-field h-32"
            @input="computeHash"
          ></textarea>
          <div class="mt-2 text-sm text-gray-500">字符数: {{ inputText.length }}</div>
        </div>

        <!-- Options -->
        <div class="mb-6 flex flex-wrap gap-4 items-center">
          <div>
            <label class="block text-sm font-medium text-gray-700 mb-1">算法</label>
            <select v-model="algorithm" class="form-select">
              <option value="SHA-1">SHA-1</option>
              <option value="SHA-256">SHA-256</option>
              <option value="SHA-384">SHA-384</option>
              <option value="SHA-512">SHA-512</option>
            </select>
          </div>

          <label class="inline-flex items-center space-x-2 text-sm text-gray-700">
            <input type="checkbox" v-model="uppercase" class="form-checkbox" />
            <span>大写</span>
          </label>

          <div class="ml-auto flex items-center gap-3">
            <button @click="computeHash" class="primary-button" :disabled="!inputText">计算哈希</button>
            <button @click="clearAll" class="secondary-button">清空内容</button>
            <button @click="loadSample" class="secondary-button">加载示例</button>
          </div>
        </div>

        <!-- Output Area -->
        <div class="mb-6">
          <label class="block text-sm font-medium text-gray-700 mb-2">哈希结果</label>
          <textarea
            v-model="outputText"
            readonly
            class="textarea-field h-20 bg-gray-50"
            placeholder="哈希结果将显示在此处..."
          ></textarea>
          <div class="mt-2 flex justify-between items-center">
            <span class="text-sm text-gray-500">算法: {{ algorithm }} • 格式: {{ uppercase ? '大写' : '小写' }}</span>
            <button
              @click="copyToClipboard"
              class="secondary-button text-sm py-2 px-4"
              :disabled="!outputText"
            >
              {{ copied ? '已复制' : '复制结果' }}
            </button>
          </div>
        </div>

        <!-- File Hashing -->
        <div class="mt-4 flex flex-col sm:flex-row sm:items-center sm:justify-between gap-3">
          <div class="flex items-center space-x-3">
            <button @click="triggerFileInput" class="secondary-button">选择文件计算 哈希</button>
            <input ref="fileInputRef" type="file" class="hidden" @change="handleFileChange" />
            <div v-if="fileInfo.name" class="text-sm text-gray-600">
              文件: {{ fileInfo.name }} • 大小: {{ fileInfo.size }} • 哈希: {{ fileInfo.hash }}
            </div>
          </div>

          <div class="flex items-center space-x-3">
            <button @click="downloadResult" class="secondary-button" :disabled="!outputText">下载结果</button>
          </div>
        </div>

        <div v-if="errorMessage" class="mt-4 p-3 bg-red-50 border border-red-200 rounded-lg">
          <p class="text-red-600 text-sm">{{ errorMessage }}</p>
        </div>
      </div>

      <!-- Instructions -->
      <div class="mt-8 bg-white rounded-xl shadow-lg p-6">
        <h3 class="text-lg font-semibold text-gray-900 mb-4">使用说明</h3>
        <ul class="space-y-2 text-gray-600">
          <li>• 输入文本或选择文件，然后点击“计算哈希”或等待自动计算。</li>
          <li>• SHA 系列是常用的散列算法：SHA-1（已不再推荐用于安全用途），建议使用 SHA-256 / SHA-384 / SHA-512。</li>
          <li>• 支持复制与下载哈希值。</li>
        </ul>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, watch } from 'vue'
import { useTools } from '@/composables/useTools'

const { copyToClipboard: toolsCopy, downloadFile } = useTools()

const inputText = ref('')
const outputText = ref('')
const copied = ref(false)
const uppercase = ref(false)
const algorithm = ref('SHA-256')
const errorMessage = ref('')
const fileInputRef = ref(null)
const fileInfo = ref({ name: '', size: '', hash: '' })

const toHex = (buffer) => {
  const bytes = new Uint8Array(buffer)
  const hex = []
  for (let i = 0; i < bytes.length; i++) {
    const h = bytes[i].toString(16).padStart(2, '0')
    hex.push(h)
  }
  return hex.join('')
}

const computeHash = async () => {
  errorMessage.value = ''
  if (!inputText.value) {
    outputText.value = ''
    return
  }
  try {
    const enc = new TextEncoder()
    const data = enc.encode(inputText.value)
    const buf = await crypto.subtle.digest(algorithm.value, data)
    let h = toHex(buf)
    if (uppercase.value) h = h.toUpperCase()
    outputText.value = h
  } catch (err) {
    errorMessage.value = '计算失败：' + (err && err.message ? err.message : String(err))
    outputText.value = ''
  }
}

const copyToClipboard = async () => {
  if (!outputText.value) return
  try {
    const ok = await toolsCopy(outputText.value)
    if (ok) {
      copied.value = true
      setTimeout(() => (copied.value = false), 2000)
    } else {
    }
  } catch (err) {
  }
}

const clearAll = () => {
  inputText.value = ''
  outputText.value = ''
  errorMessage.value = ''
  fileInfo.value = { name: '', size: '', hash: '' }
}

const loadSample = () => {
  inputText.value = 'Hello, 世界! 这是 SHA 示例'
  computeHash()
}

const triggerFileInput = () => {
  if (fileInputRef.value) fileInputRef.value.click()
}

const handleFileChange = (e) => {
  const file = e.target.files && e.target.files[0]
  if (!file) return
  errorMessage.value = ''
  const reader = new FileReader()
  reader.onload = async (ev) => {
    try {
      const ab = ev.target.result
      const buf = await crypto.subtle.digest(algorithm.value, ab)
      let out = toHex(buf)
      if (uppercase.value) out = out.toUpperCase()
      fileInfo.value = { name: file.name, size: formatSize(file.size), hash: out }
      outputText.value = out
    } catch (err) {
      errorMessage.value = '文件哈希失败：' + (err && err.message ? err.message : String(err))
    }
  }
  reader.onerror = () => {
    errorMessage.value = '读取文件失败'
  }
  reader.readAsArrayBuffer(file)
  e.target.value = ''
}

const formatSize = (bytes) => {
  if (bytes === 0) return '0 B'
  const k = 1024
  const sizes = ['B', 'KB', 'MB', 'GB']
  const i = Math.floor(Math.log(bytes) / Math.log(k))
  return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]
}

const downloadResult = () => {
  if (!outputText.value) return
  downloadFile(outputText.value, 'sha-hash.txt', 'text/plain')
}

// 自动在输入或算法变更时计算
watch([inputText, algorithm, uppercase], () => {
  computeHash()
})

useHead({
  title: 'SHA 哈希 - 八八在线工具',
  meta: [{ name: 'description', content: '在线 SHA-1/SHA-256/SHA-384/SHA-512 计算工具，支持文本或文件哈希并复制/下载结果' }]
})
</script>
